home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
DCC_3DE.ZIP
/
3DSC.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1996-01-25
|
10KB
|
340 lines
{ Can handle only up to 16384 faces objects
(C) X-wizard/DCC VR LABS
The chevy is converted by EMS version of this converter, }
{usage: 3DSC object.3ds object.dcc SCALE (smaller->bigger object}
{example: 3DSC object.3ds object.dcc 50}
uses crt;
type vertex=record
x:integer;
y:integer;
z:integer;
end;
cords=record
x:integer;
y:integer;
z:integer;
xy :integer;
end;
face=record
a:integer;
b:integer;
c:integer;
n:vertex;
vn:array[1..3] of vertex;
fxy :integer;
end;
vlist=array[0..($fffe div 4)-1] of ^cords;
flist=array[0..($fffe div 4)-1] of ^face;
object3d=record
faces:word;
vertices:word;
face:^flist;
vert:^vlist;
end;
var obj:array[1..1000] of ^object3d;
procedure calcnormals(var list:flist;var vl:vlist;fcount:word);
var f,f1:word;
a,b,c:word;
fc:array[1..3] of word;
a1,b1,c1:word;
x,y,z:array[1..3] of real;
tv:array[1..3] of vertex;
i,j,k,d:real;
begin;
{surface normals}
clrscr;
for F:=0 to fcount-1 do
begin;
gotoxy(1,1);
writelN('Calculating surface normals for face: ',f:5);
a:=list[f]^.a;
b:=list[f]^.b;
c:=list[f]^.c;
x[1]:=vl[a]^.x / 256;
y[1]:=vl[a]^.y / 256;
z[1]:=vl[a]^.z / 256;
x[2]:=vl[b]^.x / 256;
y[2]:=vl[b]^.y / 256;
z[2]:=vl[b]^.z / 256;
x[3]:=vl[c]^.x / 256;
y[3]:=vl[c]^.y / 256;
z[3]:=vl[c]^.z / 256;
i:=(((Y[2] - y[1]) * (Z[3] - Z[1])) - ((Z[2] - Z[1]) * (Y[3] - Y[1])));
j:=(((Z[2] - Z[1]) * (X[3] - X[1])) - ((X[2] - X[1]) * (Z[3] - Z[1])));
k:=(((X[2] - X[1]) * (Y[3] - Y[1])) - ((Y[2] - Y[1]) * (X[3] - X[1])));
d:= sqrt(((i * i) + (j * j)+ (k * k)));
if d=0 then d:=1;
i:= (i / d);
j:= (j / d);
k:= (k / d);
list[f]^.n.x:=round(i* 256);
list[f]^.n.y:=round(j* 256);
list[f]^.n.z:=round(k* 256);
end;
{vertex normals}
for F:=0 to fcount-1 do
begin;
fc[1]:=0;
fc[2]:=0;
fc[3]:=0;
a:=list[f]^.a;
b:=list[f]^.b;
c:=list[f]^.c;
tv[1].x:=0;
tv[1].y:=0;
tv[1].z:=0;
tv[2].x:=0;
tv[2].y:=0;
tv[2].z:=0;
tv[3].x:=0;
tv[3].y:=0;
tv[3].z:=0;
for F1:=0 to fcount-1 do
begin;
a1:=list[f1]^.a;
b1:=list[f1]^.b;
c1:=list[f1]^.c;
if (a=a1)or(a=b1)or(a=c1) then begin;
tv[1].x:=tv[1].x+list[f1]^.n.x;
tv[1].y:=tv[1].y+list[f1]^.n.y;
tv[1].z:=tv[1].z+list[f1]^.n.z;
fc[1]:=fc[1]+1;
end;
if (b=a1)or(b=b1)or(b=c1) then begin;
tv[2].x:=tv[2].x+list[f1]^.n.x;
tv[2].y:=tv[2].y+list[f1]^.n.y;
tv[2].z:=tv[2].z+list[f1]^.n.z;
fc[2]:=fc[2]+1;
end;
if (c=a1)or(c=b1)or(c=c1) then begin;
tv[3].x:=tv[3].x+list[f1]^.n.x;
tv[3].y:=tv[3].y+list[f1]^.n.y;
tv[3].z:=tv[3].z+list[f1]^.n.z;
fc[3]:=fc[3]+1;
end;
end;
tv[1].x:=tv[1].x div fc[1];
tv[1].y:=tv[1].y div fc[1];
tv[1].z:=tv[1].z div fc[1];
list[f]^.vn[1].x:=tv[1].x;
list[f]^.vn[1].y:=tv[1].y;
list[f]^.vn[1].z:=tv[1].z;
tv[2].x:=tv[2].x div fc[2];
tv[2].y:=tv[2].y div fc[2];
tv[2].z:=tv[2].z div fc[2];
list[f]^.vn[2].x:=tv[2].x;
list[f]^.vn[2].y:=tv[2].y;
list[f]^.vn[2].z:=tv[2].z;
tv[3].x:=tv[3].x div fc[3];
tv[3].y:=tv[3].y div fc[3];
tv[3].z:=tv[3].z div fc[3];
list[f]^.vn[3].x:=tv[3].x;
list[f]^.vn[3].y:=tv[3].y;
list[f]^.vn[3].z:=tv[3].z;
list[f]^.fxy:=0;
gotoxy(1,1);
writelN('Calculated vertex normals for face: ',f:5);
writelN('Vertex normal a.x:',tv[1].x:10);
writelN('Vertex normal a.y:',tv[1].y:10);
writelN('Vertex normal a.z:',tv[1].z:10);
writelN('Vertex normal b.x:',tv[2].x:10);
writelN('Vertex normal b.y:',tv[2].y:10);
writelN('Vertex normal b.z:',tv[2].z:10);
writelN('Vertex normal c.x:',tv[3].x:10);
writelN('Vertex normal c.y:',tv[3].y:10);
writelN('Vertex normal c.z:',tv[3].z:10);
end;
end;
procedure center(vcount:WORD;var list:vlist);
var vert:word;
cp,mx,mi:vertex;
begin;
mx.x:=list[0]^.x;
mx.y:=list[0]^.y;
mx.z:=list[0]^.z;
mi.x:=list[0]^.x;
mi.y:=list[0]^.y;
mi.z:=list[0]^.z;
for vert:=0 to vcount-1 do
begin;
if list[vert]^.x>mx.x then mx.x:=list[vert]^.x;
if list[vert]^.y>mx.y then mx.y:=list[vert]^.y;
if list[vert]^.z>mx.z then mx.z:=list[vert]^.z;
if list[vert]^.x<mi.x then mi.x:=list[vert]^.x;
if list[vert]^.y<mi.y then mi.y:=list[vert]^.y;
if list[vert]^.z<mi.z then mi.z:=list[vert]^.z;
end;
cp.x:=(mi.x+mx.x)div 2;
cp.y:=(mi.y+mx.y)div 2;
cp.z:=(mi.z+mx.z)div 2;
for vert:=0 to vcount-1 do
begin;
list[vert]^.x:=list[vert]^.x-cp.x;
list[vert]^.y:=list[vert]^.y-cp.y;
list[vert]^.z:=list[vert]^.z-cp.z;
list[vert]^.xy:=round((list[vert]^.x * list[vert]^.y)/256);
{DONT USE XY COZ PASCAL SUCKS!!!!!!!!!!!LIKE HELLL}
end;
end;
procedure saveDCC(fname:string;start,eend:word);
var f:file;
nmb,d:word;
begin;
assign(f,fname);
rewrite(f,1);
for nmb:=start to eend do
begin;
blockwrite(f,obj[nmb]^.faces,sizeof(obj[nmb]^.faces));
blockwrite(f,obj[nmb]^.vertices,sizeof(obj[nmb]^.vertices));
for d:=0 to obj[nmb]^.faces-1 do
begin;
blockwrite(f,obj[nmb]^.face^[d]^,sizeof(obj[nmb]^.face^[d]^));
end;
for d:=0 to obj[nmb]^.vertices-1 do
begin;
blockwrite(f,obj[nmb]^.vert^[d]^,sizeof(obj[nmb]^.vert^[d]^));
end;
end;
close(f);
end;
procedure readword(var f:file;var str:string);
var ch:byte;
begin;
str:='';
repeat;
blockread(f,ch,1);
if ch<>0 then str:=str+chr(ch);
until ch=0;
end;
var f:file;
objcnt:word;
chunkid:word;
filesize,nextchunk:longint;
name:string;
skip:boolean;
xtra,a,b,c,v,faces,vertices:word;
scale:real;
e:integer;
rx,ry,rz:single;
begin;
{scale:=30;}
val(paramstr(3),scale,e);
if e<>0 then begin;
writeln('error');
end;
assign(f,paramstr(1){'..\dcc.3ds'});
reset(f,1);
blockreaD(f,chunkid,2);
blockreaD(f,filesize,4);
if chunkid<>$4d4d then begin;
writeln('not a 3DS file....');
close(f);
halt;
end;
objcnt:=0;
repeat
blockreaD(f,chunkid,2);
blockreaD(f,nextchunk,4);
skip:=true;
if chunkid=$3d3d then begin;
blockreaD(f,chunkid,2);
blockreaD(f,nextchunk,4);
skip:=true;
end;
if chunkid=$4000 then begin;
readword(f,name);
writeln('Obj name:',name);
objcnt:=objcnt+1;
new(obj[objcnt]);
skip:=false;
end;
if chunkid=$4600 then begin;
writeln('A light skipped....');
dispose(obj[objcnt]);
objcnt:=objcnt-1;
end;
if chunkid=$4700 then begin;
writeln('A camera skipped....');
dispose(obj[objcnt]);
objcnt:=objcnt-1;
end;
if chunkid=$4100 then begin;
writeln('A true object loading mesh...');
skip:=false;
end;
if chunkid=$4110 then begin;
{vertex list}
blockread(f,vertices,2);
obj[objcnt]^.vertices:=vertices;
getmem(obj[objcnt]^.vert,vertices*4{sizeof(cords)});
clrscr;
for v:=0 to vertices-1 do
begin;
new(obj[objcnt]^.vert^[v]);
blockread(f,rx,4);
blockread(f,ry,4);
blockread(f,rz,4);
{X:0.253727 Y:-0.000012 Z:-20.659882}
rx:=rx/scale;
ry:=ry/scale;
rz:=rz/scale;
obj[objcnt]^.vert^[v]^.x:=round(rx*256);
obj[objcnt]^.vert^[v]^.y:=round(ry*256);
obj[objcnt]^.vert^[v]^.z:=round(rz*256);
gotoxy(1,1);
writeln('vertices:',vertices);
writeln('vertex x:',obj[objcnt]^.vert^[v]^.x);
writeln('vertex y:',obj[objcnt]^.vert^[v]^.y);
writeln('vertex z:',obj[objcnt]^.vert^[v]^.z);
end;
skip:=false;
end;
if chunkid=$4120 then begin;
{face list}
blockread(f,faces,2);
obj[objcnt]^.faces:=faces;
getmem(obj[objcnt]^.face,faces*4{sizeof(face)});
clrscr;
for v:=0 to faces-1 do
begin;
new(obj[objcnt]^.face^[v]);
blockread(f,c,2);
blockread(f,b,2);
blockread(f,a,2);
blockread(f,xtra,2);
obj[objcnt]^.face^[v]^.a:=a;
obj[objcnt]^.face^[v]^.b:=b;
obj[objcnt]^.face^[v]^.c:=c;
gotoxy(1,1);
writeln('faces:',faces:8);
writeln('face a:',obj[objcnt]^.face^[v]^.a:8);
writeln('face b:',obj[objcnt]^.face^[v]^.b:8);
writeln('face c:',obj[objcnt]^.face^[v]^.c:8);
end;
skip:=false;
end;
if skip then begin;
seek(f,filepos(f)+nextchunk-6);
end;
until eof(f);
close(f);
if objcnt=0 then begin;
writeln('No objects ....');
halt;
end;
for v:=1 to objcnt do
begin;
center(obj[v]^.vertices,obj[v]^.vert^);
calcnormals(obj[v]^.face^,obj[v]^.vert^,obj[v]^.faces);
end;
savedcc(paramstr(2){'ufo3d.dcc'},1,objcnt);
writeln(objcnt);
end.